home *** CD-ROM | disk | FTP | other *** search
/ Collection of Tools & Utilities / Collection of Tools and Utilities.iso / edit / mg2a_src.zip / REGION.C < prev    next >
C/C++ Source or Header  |  1988-08-23  |  8KB  |  292 lines

  1. /*
  2.  *        Region based commands.
  3.  * The routines in this file
  4.  * deal with the region, that magic space
  5.  * between "." and mark. Some functions are
  6.  * commands. Some functions are just for
  7.  * internal use.
  8.  */
  9. #include    "def.h"
  10.  
  11. /*
  12.  * Kill the region. Ask "getregion"
  13.  * to figure out the bounds of the region.
  14.  * Move "." to the start, and kill the characters.
  15.  */
  16. /*ARGSUSED*/
  17. killregion(f, n)
  18. {
  19.     register int    s;
  20.     REGION        region;
  21.  
  22.     if ((s=getregion(®ion)) != TRUE)
  23.         return (s);
  24.     if ((lastflag&CFKILL) == 0)        /* This is a kill type    */
  25.         kdelete();            /* command, so do magic */
  26.     thisflag |= CFKILL;            /* kill buffer stuff.    */
  27.     curwp->w_dotp = region.r_linep;
  28.     curwp->w_doto = region.r_offset;
  29.     return (ldelete(region.r_size, KFORW));
  30. }
  31.  
  32. /*
  33.  * Copy all of the characters in the
  34.  * region to the kill buffer. Don't move dot
  35.  * at all. This is a bit like a kill region followed
  36.  * by a yank.
  37.  */
  38. /*ARGSUSED*/
  39. copyregion(f, n)
  40. {
  41.     register LINE    *linep;
  42.     register int    loffs;
  43.     register int    s;
  44.     REGION        region;
  45.     VOID        kdelete();
  46.  
  47.     if ((s=getregion(®ion)) != TRUE)
  48.         return s;
  49.     if ((lastflag&CFKILL) == 0)        /* Kill type command.    */
  50.         kdelete();
  51.     thisflag |= CFKILL;
  52.     linep = region.r_linep;            /* Current line.    */
  53.     loffs = region.r_offset;        /* Current offset.    */
  54.     while (region.r_size--) {
  55.         if (loffs == llength(linep)) {    /* End of line.        */
  56.             if ((s=kinsert('\n', KFORW)) != TRUE)
  57.                 return (s);
  58.             linep = lforw(linep);
  59.             loffs = 0;
  60.         } else {            /* Middle of line.    */
  61.             if ((s=kinsert(lgetc(linep, loffs), KFORW)) != TRUE)
  62.                 return s;
  63.             ++loffs;
  64.         }
  65.     }
  66.     return TRUE;
  67. }
  68.  
  69. /*
  70.  * Lower case region. Zap all of the upper
  71.  * case characters in the region to lower case. Use
  72.  * the region code to set the limits. Scan the buffer,
  73.  * doing the changes. Call "lchange" to ensure that
  74.  * redisplay is done in all buffers.
  75.  */
  76. /*ARGSUSED*/
  77. lowerregion(f, n)
  78. {
  79.     register LINE    *linep;
  80.     register int    loffs;
  81.     register int    c;
  82.     register int    s;
  83.     REGION        region;
  84.  
  85.     if ((s=getregion(®ion)) != TRUE)
  86.         return s;
  87.     lchange(WFHARD);
  88.     linep = region.r_linep;
  89.     loffs = region.r_offset;
  90.     while (region.r_size--) {
  91.         if (loffs == llength(linep)) {
  92.             linep = lforw(linep);
  93.             loffs = 0;
  94.         } else {
  95.             c = lgetc(linep, loffs);
  96.             if (ISUPPER(c) != FALSE)
  97.                 lputc(linep, loffs, TOLOWER(c));
  98.             ++loffs;
  99.         }
  100.     }
  101.     return TRUE;
  102. }
  103.  
  104. /*
  105.  * Upper case region. Zap all of the lower
  106.  * case characters in the region to upper case. Use
  107.  * the region code to set the limits. Scan the buffer,
  108.  * doing the changes. Call "lchange" to ensure that
  109.  * redisplay is done in all buffers.
  110.  */
  111. /*ARGSUSED*/
  112. upperregion(f, n)
  113. {
  114.     register LINE    *linep;
  115.     register int    loffs;
  116.     register int    c;
  117.     register int    s;
  118.     REGION        region;
  119.     VOID        lchange();
  120.  
  121.     if ((s=getregion(®ion)) != TRUE)
  122.         return s;
  123.     lchange(WFHARD);
  124.     linep = region.r_linep;
  125.     loffs = region.r_offset;
  126.     while (region.r_size--) {
  127.         if (loffs == llength(linep)) {
  128.             linep = lforw(linep);
  129.             loffs = 0;
  130.         } else {
  131.             c = lgetc(linep, loffs);
  132.             if (ISLOWER(c) != FALSE)
  133.                 lputc(linep, loffs, TOUPPER(c));
  134.             ++loffs;
  135.         }
  136.     }
  137.     return TRUE;
  138. }
  139.  
  140. /*
  141.  * This routine figures out the bound of the region
  142.  * in the current window, and stores the results into the fields
  143.  * of the REGION structure. Dot and mark are usually close together,
  144.  * but I don't know the order, so I scan outward from dot, in both
  145.  * directions, looking for mark. The size is kept in a long. At the
  146.  * end, after the size is figured out, it is assigned to the size
  147.  * field of the region structure. If this assignment loses any bits,
  148.  * then we print an error. This is "type independent" overflow
  149.  * checking. All of the callers of this routine should be ready to
  150.  * get an ABORT status, because I might add a "if regions is big,
  151.  * ask before clobberring" flag.
  152.  */
  153. getregion(rp) register REGION *rp; {
  154.     register LINE    *flp;
  155.     register LINE    *blp;
  156.     register long    fsize;            /* Long now.        */
  157.     register long    bsize;
  158.  
  159.     if (curwp->w_markp == NULL) {
  160.         ewprintf("No mark set in this window");
  161.         return (FALSE);
  162.     }
  163.     if (curwp->w_dotp == curwp->w_markp) {    /* "r_size" always ok.    */
  164.         rp->r_linep = curwp->w_dotp;
  165.         if (curwp->w_doto < curwp->w_marko) {
  166.             rp->r_offset = curwp->w_doto;
  167.             rp->r_size = (RSIZE) (curwp->w_marko-curwp->w_doto);
  168.         } else {
  169.             rp->r_offset = curwp->w_marko;
  170.             rp->r_size = (RSIZE) (curwp->w_doto-curwp->w_marko);
  171.         }
  172.         return TRUE;
  173.     }
  174.     flp = blp = curwp->w_dotp;        /* Get region size.    */
  175.     bsize = curwp->w_doto;
  176.     fsize = llength(flp)-curwp->w_doto+1;
  177.     while (lforw(flp)!=curbp->b_linep || lback(blp)!=curbp->b_linep) {
  178.         if (lforw(flp) != curbp->b_linep) {
  179.             flp = lforw(flp);
  180.             if (flp == curwp->w_markp) {
  181.                 rp->r_linep = curwp->w_dotp;
  182.                 rp->r_offset = curwp->w_doto;
  183.                 return (setsize(rp,
  184.                     (RSIZE) (fsize+curwp->w_marko)));
  185.             }
  186.             fsize += llength(flp)+1;
  187.         }
  188.         if (lback(blp) != curbp->b_linep) {
  189.             blp = lback(blp);
  190.             bsize += llength(blp)+1;
  191.             if (blp == curwp->w_markp) {
  192.                 rp->r_linep = blp;
  193.                 rp->r_offset = curwp->w_marko;
  194.                 return (setsize(rp,
  195.                     (RSIZE) (bsize-curwp->w_marko)));
  196.             }
  197.         }
  198.     }
  199.     ewprintf("Bug: lost mark");        /* Gak!            */
  200.     return FALSE;
  201. }
  202.  
  203. /*
  204.  * Set size, and check for overflow.
  205.  */
  206. setsize(rp, size) register REGION *rp; register RSIZE size; {
  207.  
  208.     rp->r_size = size;
  209.     if (rp->r_size != size) {
  210.         ewprintf("Region is too large");
  211.         return FALSE;
  212.     }
  213.     return TRUE;
  214. }
  215.  
  216. #ifdef    PREFIXREGION
  217. /*
  218.  * Implements one of my favorite keyboard macros; put a string at the
  219.  * beginning of a number of lines in a buffer.    The quote string is
  220.  * settable by using set-prefix-string.     Great for quoting mail, which
  221.  * is the real reason I wrote it, but also has uses for creating bar
  222.  * comments (like the one you're reading) in C code.
  223.  */
  224.  
  225. #define PREFIXLENGTH 40
  226. static char prefix_string[PREFIXLENGTH] = { '>', '\0' };
  227.  
  228. /*
  229.  * Prefix the region with whatever is in prefix_string.
  230.  * Leaves dot at the beginning of the line after the end
  231.  * of the region.  If an argument is given, prompts for the
  232.  * line prefix string.
  233.  */
  234.  
  235. /*ARGSUSED*/
  236. prefixregion(f, n)
  237. {
  238.     register int    s;
  239.     register LINE    *first, *last;
  240.     register int    nline;
  241.     REGION        region;
  242.     char        *prefix = prefix_string;
  243.  
  244.     if ((f == TRUE) && ((s = setprefix(FFRAND, 1)) != TRUE))
  245.         return s;
  246.  
  247.     /* get # of lines to affect */
  248.     if ((s = getregion(®ion)) != TRUE)
  249.         return (s);
  250.     first = region.r_linep;
  251.     last = (first == curwp->w_dotp) ? curwp->w_markp : curwp->w_dotp;
  252.     for (nline = 1; first != last; nline++)
  253.         first = lforw(first);
  254.  
  255.     /*move to beginning of region */
  256.     curwp->w_dotp = region.r_linep;
  257.     curwp->w_doto = region.r_offset;
  258.  
  259.     /* for each line, go to beginning and insert the prefix string */
  260.     while (nline--) {
  261.         (VOID) gotobol(FFRAND, 1);
  262.         for (prefix = prefix_string; *prefix; prefix++)
  263.             (VOID) linsert(1, *prefix);
  264.         (VOID) forwline(FFRAND, 1);
  265.     }
  266.     (VOID) gotobol(FFRAND, 1);
  267.     return TRUE;
  268. }
  269.  
  270. /*
  271.  * Set prefix string.
  272.  */
  273.  
  274. /*ARGSUSED*/
  275. setprefix(f, n)
  276. {
  277.     char        buf[PREFIXLENGTH];
  278.     register int    s;
  279.  
  280.     if (prefix_string[0] == '\0')
  281.         s = ereply("Prefix string: ",buf,sizeof buf);
  282.     else
  283.         s = ereply("Prefix string (default %s): ",
  284.                 buf,sizeof buf,prefix_string);
  285.     if (s == TRUE)
  286.         (VOID) strcpy(prefix_string, buf);
  287.     if ((s == FALSE) && (prefix_string[0] != '\0')) /* CR -- use old one */
  288.         s = TRUE;
  289.     return s;
  290. }
  291. #endif
  292.